/**
 * app 图标级联选择
 */

;(function($) {

    var mainCategoryCodeMap ={
        CATEGORY: 'productSearch', // app 的方法
        DETAIL: 'productDetail',
        MORE: 'more',
        CUSTOM: 'custom',
    };



    function I18n(local) {
        var language = {
            en:{
                categories: 'categories',
                detail: 'Product',
                more: 'More',
                custom: 'Custom',
                placeholder: 'Press enter key to search',
                confirm: 'Confirm',
                bestseller: 'Bestseller',
                featured: 'Featured',
                latest: 'Latest',
                special: 'Special'

            },
            zh_cn: {
                categories: '产品分类',
                detail: '产品详情',
                more: '产品专区',
                custom: '自定义',
                placeholder: '按下回车键盘进行搜索',
                confirm: '确认',
                bestseller: '热卖',
                featured: '推荐',
                latest: '最新',
                special: '特价',
            }
        };

        var defaultLocal = 'zh_cn';
        this.language = language;
        this.local = (local in language) ? local: defaultLocal;
    };

    I18n.prototype.t = function (name) {
        return this.language[this.local][name] || name;
    };

    /**
     * 自定义选择面板
     * @param parent
     * @constructor
     */
    function CustomPanel(parent, i18n) {
        this.value = '';
        this.$parent = parent;
        this.$panel = null;
        this.i18n = i18n;
        this.init();
    }

    CustomPanel.prototype = {
        /**
         * 初始化组件
         */
        init: function () {
            this.drawUi();
            this.bindEvents();
        },

        /**
         * 绘制UI
         */
        drawUi: function () {
            var html = '<input name="custom-link" value="" /><button>'+ this.i18n.t('confirm') +'</button>';
            this.$panel = $('<div class="cascade-content-panel-custom">'+html+'</div>');
        },

        /**
         * 绑定事件
         */
        bindEvents: function () {
            self = this;
            this.$panel.find("button").click(function () {
                self.value = self.$panel.find("input").val();
                self.$parent.trigger('confirm.custom', {url: self.value});
            })
        },

        /**
         * 挂载到容器
         * @param container
         */
        mountTo: function (container) {
            container.append(this.$panel);
        },

        /**
         * 设置值
         * @param url
         */
        setValue: function(url){
            this.value = url || '';
            this.$panel.find('input').val(this.value);
        },

        /**
         * 选择选择面板的选项
         * @param optionConfig
         */
        setSelectedOptions: function (optionConfig) {
            if (optionConfig.mainCategory !== mainCategoryCodeMap.CUSTOM) {
                return;
            }
            this.$panel.show();
            if(optionConfig.config){
                this.setValue(optionConfig.config.url)
            }
        }
    };

    /**
     *  分类面板
     * @param parent
     * @param categories
     * @constructor
     */
    function CategoryPanel(parent, categories, i18n) {
        this.categories = categories;
        this.$panel =null;
        this.$parent = parent;
        this.init();
        this.i18n = i18n;
        this.categoryId = '';
    };

    CategoryPanel.prototype = {
        /**
         * 初始化分类面板
         */
        init: function () {
            this.drawUi();
            this.bindEvents();
        },

        /**
         * 绘制UI
         */
        drawUi: function () {
            var categoryHtml =  this.categories.map(function (item) {
                return '<li class="categories-item" data-value="'+item.category_id+'">'+item.name+'</li>'
            }).join('');
            this.$panel = $('<div class="cascade-content-panel-categories"><ul class="categories">'+categoryHtml+'</ul></div>')
        },

        /**
         * 绑定事件
         */
        bindEvents: function(){
            var self = this;
            this.$panel.find(".categories-item").click(function (event) {
                var categoryId = event.currentTarget.dataset.value;
                self.selectCategory(categoryId);
                self.$parent.trigger("confirm.category", {id: self.categoryId});
            })
        },

        /**
         * 挂载到容器
         * @param container
         */
        mountTo: function (container) {
            container.append(this.$panel);
        },

        /**
         * 选择分类
         * @param categoryId
         */
        selectCategory: function(categoryId){
            if (categoryId) {
                this.categoryId = categoryId;
                this.$panel
                    .find(".categories-item")
                    .removeClass('active')
                    .each(function (index, item) {
                        if(item.dataset.value.toString() === categoryId) {
                            $(item).addClass('active');
                        }
                    })
            }
        },

        /**
         * 设置面板的配置
         * @param optionConfig
         */
        setSelectedOptions: function (optionConfig) {
            if (optionConfig.mainCategory !== mainCategoryCodeMap.CATEGORY) {
                return;
            }
            this.$panel.show();
            if(optionConfig.config){
                this.selectCategory(optionConfig.config.categoryId);
            }
        }
    };

    /**
     * 商品面板
     * @param parent
     * @param productsUrl
     * @constructor
     */
    function ProductPanel(parent, productsUrl, i18n) {
        this.productsUrl = productsUrl;
        this.id = '';// 商品id
        this.$parent = parent;
        this.$panel = null;
        this.i18n = i18n;
        this.init();
    }

    ProductPanel.prototype = {
        /**
         * 初始化商品面板
         */
        init: function () {
            this.drawUi();
            this.bindEvents();
        },

        /**
         * 绘制UI
         */
        drawUi: function () {
            this.$panel = $(
                '<div class="cascade-content-panel-product">' +
                    '<div class="cascade-content-panel-product-search">' +
                        '<input value="" name="search_product_id" placeholder="'+this.i18n.t('placeholder')+'"/>' +
                    '</div>'+
                    '<ul class="cascade-content-panel-product-list"></ul>' +
                '</div>')
        },

        /**
         * 绑定事件
         */
        bindEvents: function () {
            var self = this;

            /**
             * 处理请求得到的商品数据
             * @param products
             */
            function handleProductsData(products){
                var liHtml = $.map(products, function (item) {
                    return '<li class="cascade-content-panel-product-list-item" data-value="'+item.product_id+'">'+item.name+'</li>'
                }).join("")
                self.$panel.find('.cascade-content-panel-product-list').html(liHtml);
            };

            /**
             * 搜索商品
             * @param productName
             */
            function searchProduct(productName) {
                var url = self.productsUrl+'&filter_name='+ productName;
                $.ajax(url).success(function (products) {
                    handleProductsData(products);
                }).error(function (error) {
                    layer.open({
                        skin: 'layer-alert',
                        btnAlign: 'c',
                        title: ' ',
                        content: error.message || error.statusText
                    });
                })
            };

            /**
             * 监听商品名称聚焦事件
             */
            this.$panel.find("input[name='search_product_id']").focus(function (event) {
                var input = $(event.currentTarget);
                searchProduct(input.val())
            });

            /**
             * 监听enter事件
             */
            this.$panel.find("input[name='search_product_id']").keyup(function () {
                if(event.keyCode==13){
                    var input = $(event.currentTarget);
                    searchProduct(input.val());
                }
            });

            /**
             * 监听商品被点击(选中)
             */
            this.$panel.on('click', '.cascade-content-panel-product-list-item', function (event) {
                var value = event.currentTarget.dataset.value;
                self.id = value;
                self.$parent.trigger('confirm.product', {id: self.id});
            })
        },

        /**
         * 挂载到容器
         * @param container
         */
        mountTo: function(container){
            container.append(this.$panel);
        },

        /**
         * 设置面板配置
         * @param optionConfig
         */
        setSelectedOptions: function (optionConfig) {
            if (optionConfig.mainCategory !== mainCategoryCodeMap.DETAIL) {
                return;
            }
            this.$panel.show();
        }
    };


    /**
     * 模块面板
     * @param parent
     * @param moduleGroups
     * @constructor
     */
    function MorePanel(parent, moduleGroups, i18n) {
        this.moduleGroups = moduleGroups;
        this.$morePanel = null;
        this.$parent = parent;
        this.groupName = '';
        this.moduleId = '';
        this.i18n = i18n;
        this.init();
    };

    MorePanel.prototype = {
        /**
         * 初始化更多面板
         */
        init: function () {
            this.drawUi();
            this.addEvents();
        },

        /**
         * 绘制UI
         */
        drawUi: function () {
            var modulesHtml = '';
            $.each(this.moduleGroups, function (groupName, modules) {
                 var html = modules.map(function (item) {
                    return '<li class="more-group-item-modules-item" data-value="'+item.module_id+'">'+item.name+'</li>'
                 }).join('');
                 modulesHtml += '<ul class="more-group-item-modules '+groupName+'">'+html+'</ul>';
            });

            var groupHtml =
                '<ul class="more-group">' +
                    '<li class="more-group-item" data-value="bestseller">'+this.i18n.t("bestseller")+'</li>' +
                    '<li class="more-group-item" data-value="featured">'+this.i18n.t("featured")+'</li>' +
                    '<li class="more-group-item" data-value="latest">'+this.i18n.t("latest")+'</li>' +
                    '<li class="more-group-item" data-value="special">'+this.i18n.t("special")+'</li>' +
                '</ul>';

            this.$morePanel = $('<div class="cascade-content-panel-more clearfix">'+groupHtml+ modulesHtml+'</div>')
        },

        /**
         * 绑定事件
         */
        addEvents: function(){
            var self = this;
            /**
             * 监听模块组(更多类型)被点击(选中)
             */
            this.$morePanel.find('.more-group-item').click(function (evnet) {
                var groupName = evnet.currentTarget.dataset.value;
                if (groupName){
                    self.selectModuleGroup(groupName);
                }
            });

            /**
             * 监听模块被点击(选中)
             */
            this.$morePanel.find('.more-group-item-modules-item').click(function (evnet) {
                var moduleId = evnet.currentTarget.dataset.value;
                if (moduleId){
                    self.selectModuleItem(moduleId);
                    self.$parent.trigger("confirm.more",{groupName: self.groupName, moduleId: self.moduleId});
                }
            });
        },

        /**
         * 选择模块组(模块类型)
         * @param groupName
         */
        selectModuleGroup: function(groupName){
            this.groupName = groupName || '';
            var self = this;
            this.$morePanel.find('.more-group-item').removeClass('active');
            self.$morePanel.find('.more-group-item-modules').hide();

            if(this.groupName){
                this.$morePanel.find('.more-group-item[data-value="'+this.groupName+'"]').addClass('active');
                this.$morePanel.find('.more-group-item-modules.'+this.groupName).show();
            }
        },

        /**
         * 选择模块
         * @param moduleId
         */
        selectModuleItem: function(moduleId){
            this.moduleId = moduleId || '';
            if (this.moduleId){
                this.$morePanel.find('.more-group-item-modules-item').removeClass('active');
                this.$morePanel.find('[data-value="'+moduleId+'"]').addClass('active');
            }
        },

        /**
         * 挂载到容器
         * @param container
         */
        mountTo: function (container) {
            container.append(this.$morePanel);
        },

        /**
         * 设置选择的配置
         * @param optionConfig
         */
        setSelectedOptions: function (optionConfig) {
            if (optionConfig.mainCategory !== mainCategoryCodeMap.MORE) {
                return;
            }
            this.$morePanel.show();
            this.selectModuleGroup(optionConfig.config.search_type);
            this.selectModuleItem(optionConfig.config.layout_module_id)
        }
    };

    /**
     * 联级选择器
     * @param options
     * @constructor
     */
    function CascadeSelector(options) {
        this.i18n = new I18n(options.local);
        /**
         *认配置
         * @type {{isChinese: boolean, url: string, mainOptions: *[], api: {categories: string, module: string, products: string}, data: {categories: Array, moduleGroups: Array}}}
         */
        var defaultOptions = {
            local : 'zh_cn',
            url: '',
            mainOptions: [
                {
                    name: this.i18n.t('categories'),
                    mainCategoriesCode: mainCategoryCodeMap.CATEGORY,
                },
                {
                    name: this.i18n.t('detail'),
                    mainCategoriesCode: mainCategoryCodeMap.DETAIL,
                },
                {
                    name: this.i18n.t('more'),
                    mainCategoriesCode: mainCategoryCodeMap.MORE,
                },
                {
                    name: this.i18n.t('custom'),
                    mainCategoriesCode: mainCategoryCodeMap.CUSTOM,
                }
            ],
            api: {
                categories: '',
                module: '',
                products:'',
            },
            data: {
                categories: [],
                moduleGroups: [],
            },
        };

        this.$cascade = null;
        this.options = $.extend( defaultOptions, options, true );
        this.hooks = {
            ready: [],
            error: [],
            confirm: [],
        };
        this.panels = {
            [mainCategoryCodeMap.CUSTOM]: null,
            [mainCategoryCodeMap.MORE]: null,
            [mainCategoryCodeMap.CATEGORY]: null,
            [mainCategoryCodeMap.DETAIL]: null,
        };
        // this.parseUrlSchema();
        this.fetchData()
            .fail(function (error) {
                this.alert(error.message);
                $.each(this.hooks.error, $.proxy(function (index, cb) {
                    cb.call(this, error);
                }, this))
            })
            .done(function () {
                this.initCascade();
                $.each(this.hooks.ready, $.proxy(function (index, cb) {
                    cb.call(this);
                }, this))
            });
    };

    /**
     * 获取联级分类插件的实例
     */
    CascadeSelector.getInstance = (function () {
        var cs = null;
        return function (options) {
            if (!cs) {
                cs = new CascadeSelector(options);
            }
            return cs;
        };
    })();

    CascadeSelector.prototype = {

        /**
         * 初始完成时执行
         * @param callback
         * @returns {CascadeSelector}
         */
        ready: function(callback){
            callback = callback || $.noop;
            this.hooks.ready.push(callback);
            return this;
        },

        /**
         * 错误时执行
         * @param callback
         * @returns {CascadeSelector}
         */
        error: function(callback){
            callback = callback || $.noop;
            this.hooks.error.push(callback);
            return this;
        },

        /**
         * 确认时执行 只执行一次.
         * @param callback
         * @returns {CascadeSelector}
         */
        onceConfirm: function(callback){
            callback = callback || $.noop;
            this.hooks.confirm.push(callback);
            return this;
        },

        /**
         * 请求数据
         * @returns {*}
         */
        fetchData: function(){
            var defer = $.Deferred();
            $.when($.ajax(this.options.api.categories), $.ajax(this.options.api.module))
                .then($.proxy(function(categoriesResponse, moduleResponse){
                    if(categoriesResponse[0].code !== 0){
                        defer.rejectWith(this, categoriesResponse[0].error);
                    } else if( moduleResponse[0].code !== 0){
                        defer.rejectWith(this, moduleResponse[0].error);
                    } else{
                        this.options.data.moduleGroups = moduleResponse[0].module_group;
                        this.options.data.categories = categoriesResponse[0].categories;
                        defer.resolveWith(this, this.options.data.moduleGroups, this.options.data.categories)
                    }
                }, this));
            return defer.promise();
        },

        /**
         * 初始化级联插件
         */
        initCascade: function (){
            this.drawUi();
            this.createPanels();
            this.bindEvents();
            this.mount();
        },

        /**
         * 创建面板插件
         */
        createPanels: function(){
            this.panels[mainCategoryCodeMap.MORE] = new MorePanel(this.$cascade, this.options.data.moduleGroups, this.i18n);
            this.panels[mainCategoryCodeMap.CATEGORY] = new CategoryPanel(this.$cascade, this.options.data.categories, this.i18n);
            this.panels[mainCategoryCodeMap.DETAIL] = new ProductPanel(this.$cascade, this.options.api.products, this.i18n);
            this.panels[mainCategoryCodeMap.CUSTOM] = new CustomPanel(this.$cascade, this.i18n);
        },

        /**
         * 报错
         * @param error
         */
        alert: function(error) {
            layer.open({
                skin: 'layer-alert',
                btnAlign: 'c',
                title: ' ',
                content: error.message || error.statusText
            });
        },

        /**
         * 绘制UI
         * @returns {null|*}
         */
        drawUi: function(){
            var tabsHtml = $.map(this.options.mainOptions, function (item) {
                return '<li class="cascade-tabs-item" data-category="'+item.mainCategoriesCode+'">'+item.name+'<i class="icon-arrow-right"></i></li>'
            }).join('');
            this.$cascade = $(
                '<div class="cascadeSelector clearfix">' +
                    '<ul class="cascade-tabs level-1">'+tabsHtml+'</ul>' +
                    '<div class="cascade-content">' +
                    '</div>' +
                '</div>');
            return this.$cascade;
        },

        /**
         * 绑定事件
         */
        bindEvents: function(){
            var self = this;
            /**
             *  处理主分类被点击
             */
            this.$cascade.find('.cascade-tabs-item').on('click', function (event) {
                var mainCategoryCode = event.currentTarget.dataset.category;
                // 清除选择的
                $(event.currentTarget).parent().children().removeClass('active');
                $(event.currentTarget).addClass('active');
                switch (mainCategoryCode) {
                    case mainCategoryCodeMap.CATEGORY:
                        self.setSelectedOptions({mainCategory: mainCategoryCodeMap.CATEGORY, config:{}});
                        break;
                    case mainCategoryCodeMap.DETAIL:
                        self.setSelectedOptions({mainCategory: mainCategoryCodeMap.DETAIL, config:{}});
                        break;
                    case mainCategoryCodeMap.MORE:
                        self.setSelectedOptions({mainCategory: mainCategoryCodeMap.MORE, config:{}});
                        break;
                    case mainCategoryCodeMap.CUSTOM:
                        self.setSelectedOptions({mainCategory: mainCategoryCodeMap.CUSTOM});
                        break;
                    default:
                        break;
                }
            });

            /**
             * 点击文档时关闭级联插件
             */
            $(document).click(function (event) {
                if(!$.contains(self.$cascade[0], event.target)){
                    self.close();
                }

            });

            /**
             * 调用确认事件然后清空确认事件
             * @param url
             */
            function invokeOnceConfirm(url) {
                $.each(self.hooks.confirm, $.proxy(function (index, cb) {
                    cb.call(self, url);
                }, this));
                self.hooks.confirm = [];
            }

            /**
             * 监听自定义面板确认选择
             */
            this.$cascade.on('confirm.custom', function (event, result) {
                invokeOnceConfirm(result.url);
                self.close();
            });

            /**
             * 监听商品面板确认选择
             */
            this.$cascade.on('confirm.product', function (event, result) {
                var url = 'app://'+ mainCategoryCodeMap.DETAIL+ '?id=' + result.id;
                invokeOnceConfirm(url);
                self.close();
            });

            /**
             * 监听模块面板确认选择
             */
            this.$cascade.on('confirm.more', function (event, result) {
                var parameter = '{#domain_name#}#/more?search_type='+result.groupName+'&module_id='+result.moduleId;
                var url = 'app://'+ mainCategoryCodeMap.MORE+ '?url=' + encodeURIComponent(parameter);
                invokeOnceConfirm(url);
                self.close();
            });

            /**
             * 监听确认分类面板确认事件
             */
            this.$cascade.on('confirm.category', function (event, result) {
                var url = 'app://'+ mainCategoryCodeMap.CATEGORY+ '?category_id=' + result.id;
                invokeOnceConfirm(url);
                self.close();
            });
        },

        /**
         * 挂载各个面板插件到级联插件, 级联插件挂载到 document
         */
        mount: function(){
            var $content = this.$cascade.find('.cascade-content');
            this.panels[mainCategoryCodeMap.MORE].mountTo($content);
            this.panels[mainCategoryCodeMap.CATEGORY].mountTo($content);
            this.panels[mainCategoryCodeMap.CUSTOM].mountTo($content);
            this.panels[mainCategoryCodeMap.DETAIL].mountTo($content);
            $('body').append(this.$cascade);
        },

        /**
         * 关闭级联插件
         */
        close: function(){
            this.$cascade.hide();
        },

        /**
         * 设置插件的位置
         * @param offsetLeft
         * @param offsetTop
         */
        setPosition: function (offsetLeft, offsetTop) {
            this.$cascade.css({
                top: offsetTop,
                left: offsetLeft,
                display: 'inline-block'
            });
        },

        setSelectedOptions: function(optionConfig){
            var categoryCode = optionConfig.mainCategory || mainCategoryCodeMap.CATEGORY;
            this.$cascade.find('.level-1 li').each(function (index, item) {
                if (item.dataset.category === categoryCode) {
                    $(item).addClass('active')
                } else{
                    $(item).removeClass('active')
                }
            });
            this.$cascade.find(".cascade-content > div").hide();

            if (optionConfig.mainCategory && optionConfig.mainCategory) {
                var $panel = this.panels[optionConfig.mainCategory];
                $panel.setSelectedOptions.call($panel, optionConfig);
            }

        },
    };

    /**
     * 绑定插件
     * @param options
     */
    $.fn.cascadeSelector = function( options ) {

        var cs = CascadeSelector.getInstance(options);

        /**
         * 解析 app url
         * @param url
         * @returns {{mainCategory: (*|string), config: *}}
         */
         function parseUrlSchema(url) {
            var url_prefix_reg = /^app:\/\//i;
            var splittedUrl = url.replace(url_prefix_reg, '').split('?');
            var methodName = splittedUrl[0] || '';
            var parameters = decodeURIComponent(splittedUrl[1]);
            var config = null;
            switch (methodName) {
                case mainCategoryCodeMap.CATEGORY:
                    config = {'categoryId': parameters.replace(/^.+?=/, '')};
                    break;
                case mainCategoryCodeMap.MORE:
                    var webViewParameter = parameters.replace(/^.+?\?/, '');
                    config =  Qs.parse(webViewParameter);
                    break;
                case mainCategoryCodeMap.DETAIL:
                    config =  Qs.parse(webViewParameter);
                    break;
                default:
                    methodName = mainCategoryCodeMap.CUSTOM;
                    config = { 'url' : url};
                    break;
            }
            return {
                mainCategory: methodName,
                config: config
            }
        };

         var $input = $(event.target);
        /**
         * 处理input被点击取消冒泡, 防止点击后事件冒泡导致关闭级联插件.
         * 级联插件通过监听文档被点击事件绑定方法来关闭.
         */
        $input.click(function (evnet) {
            evnet.stopPropagation();
        });

        /**
         * 处理 resize
         */
        $(window).resize(function () {
            var offsetTop = $input.offset().top + $input.outerHeight() +'px';
            var offsetLeft = $input.offset().left + 'px';
            cs.setPosition(offsetLeft, offsetTop);
        });

         var offsetTop = $input.offset().top + $input.outerHeight() +'px';
         var offsetLeft = $input.offset().left + 'px';
         var urlInfo = parseUrlSchema($input.val());

        /**
         * 组件初始化完成后执行
         */
        cs.ready(function () {
             cs.setPosition(offsetLeft, offsetTop);
             cs.setSelectedOptions(urlInfo);
         }).error(function (error) {
             alert((error.message))
         });

         if (cs && cs.$cascade){
             cs.setPosition(offsetLeft, offsetTop);
             cs.setSelectedOptions(urlInfo);
         }

        /**
         * 确认后执行回调, 由于 cs 是单例. 因此绑定的方法执行后会被清空.
         * 防止 callback 被缓存起来.
         */
        cs.onceConfirm(function (value) {
            $input.val(value);
            console.log($input, 'confirm');
        });

    }


})(window.jQuery);



